package com.yummiii.dokueditor.controller;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.xmlrpc.XmlRpcException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import com.yummiii.dokueditor.model.doku.DokuNSElement;
import com.yummiii.dokueditor.model.doku.DokuNamespace;
import com.yummiii.dokueditor.model.doku.DokuPage;

public class MainController {
	PrefController prefController;
	DokuController dokuController;
	DataController dataController;

	HashMap<TreeItem, DokuPage> pageMap;

	public MainController() throws FileNotFoundException, IOException {
		prefController = new PrefController();
		dokuController = new DokuController(prefController);
		pageMap = new HashMap<TreeItem, DokuPage>();
	}

	public Tree getTree(Shell shell) throws MalformedURLException,
			XmlRpcException {
		Tree tree = new Tree(shell, SWT.BORDER_SOLID);
		setTree(tree, dokuController);
		return tree;
	}
	
	public String getText(TreeItem treeItem) throws MalformedURLException, XmlRpcException{
		if(pageMap.get(treeItem)==null)
			return "This Page does not exist.";
		return dokuController.getPage(pageMap.get(treeItem));
	}

	public ToolBar getDummyToolbar(Shell shell,Display display){
		Image image = new Image (display, 16, 16);
		Color color = display.getSystemColor (SWT.COLOR_GREEN);
		GC gc = new GC (image);
		gc.setBackground (color);
		gc.fillRectangle (image.getBounds ());
		gc.dispose ();
		ToolBar toolBar = new ToolBar (shell, SWT.FLAT | SWT.BORDER);
		Rectangle clientArea = shell.getClientArea ();
		toolBar.setLocation (clientArea.x, clientArea.y);
		for (int i=0; i<12; i++) {
			int style = i % 3 == 2 ? SWT.DROP_DOWN : SWT.PUSH;
			ToolItem item = new ToolItem (toolBar, style);
			item.setImage (image);
		}
		toolBar.pack ();
		return toolBar;
	}
	
	public Menu getDummyMenu(Shell shell){
		Menu bar= new Menu(shell,SWT.BAR);
		
		MenuItem fileItem = new MenuItem (bar, SWT.CASCADE);
		fileItem.setText ("&File");
		Menu submenu = new Menu (shell, SWT.DROP_DOWN);
		fileItem.setMenu (submenu);
		MenuItem item = new MenuItem (submenu, SWT.PUSH);
		item.addListener (SWT.Selection, new Listener () {
			public void handleEvent (Event e) {
				System.out.println ("Select All");
			}
		});
		item.setText ("Select &All\tCtrl+A");
		item.setAccelerator (SWT.MOD1 + 'A');
		return bar;
	}
	
	public StyledText getDummyText(Shell shell, Display display) {
		StyledText text = new StyledText(shell, SWT.V_SCROLL|SWT.BORDER_SOLID);
		text.setText("0123456789 ABCDEFGHIJKLM NOPQRSTUVWXYZ lsadkjflökadjsfölkajsdf");
		// make 0123456789 appear bold
		StyleRange style1 = new StyleRange();
		style1.start = 0;
		style1.length = 10;
		style1.fontStyle = SWT.BOLD;
		text.setStyleRange(style1);
		// make ABCDEFGHIJKLM have a red font
		StyleRange style2 = new StyleRange();
		style2.start = 11;
		style2.length = 13;
		style2.foreground = display.getSystemColor(SWT.COLOR_RED);
		text.setStyleRange(style2);
		// make NOPQRSTUVWXYZ have a blue background
		StyleRange style3 = new StyleRange();
		style3.start = 25;
		style3.length = 13;
		style3.background = display.getSystemColor(SWT.COLOR_BLUE);
		text.setStyleRange(style3);
		text.setWordWrap(true);
		return text;
	}

	private void setTree(Tree tree, DokuController dokuController)
			throws MalformedURLException, XmlRpcException {
		DokuNamespace root = dokuController.getPagelist("");
		HashMap<String, TreeItem> checklist = new HashMap<String, TreeItem>();

		List<Map.Entry<String, DokuNSElement>> entrylist = new ArrayList(root
				.getChildren().entrySet());
		Collections.sort(entrylist, new Comparator() {
			public int compare(Object o1, Object o2) {
				return ((Map.Entry<String, DokuNamespace>) o1).getKey()
						.compareTo(
								((Map.Entry<String, DokuNamespace>) o2)
										.getKey());
			}
		});

		for (Map.Entry<String, DokuNSElement> me : entrylist) {
			// System.out.println("class==>"+me.getValue().getClass());
			if (me.getValue().getClass() == DokuNamespace.class) {
				String name = ((DokuNamespace) me.getValue()).getName();
				TreeItem treeItem;
				if (!checklist.containsKey(name)) {
					treeItem = new TreeItem(tree, 8);
					treeItem.setText(name);
					checklist.put(name, treeItem);
					pageMap.put(treeItem, null);
				} else {
					treeItem = checklist.get(name);
				}
				setTreeItem(treeItem, (DokuNamespace) me.getValue());
			} else if (me.getValue().getClass() == DokuPage.class) {
				String name = ((DokuPage) me.getValue()).getName();
				if (!checklist.containsKey(name)) {
					TreeItem treeItem = new TreeItem(tree, 0);
					treeItem.setText(name);
					checklist.put(name, treeItem);
					pageMap.put(treeItem, (DokuPage) me.getValue());
				} else {
					TreeItem treeItem = checklist.get(name);
					pageMap.remove(treeItem);
					pageMap.put(treeItem, (DokuPage) me.getValue());
				}
			}
		}
	}

	private void setTreeItem(TreeItem tree, DokuNamespace namespace) {
		HashMap<String, TreeItem> checklist = new HashMap<String, TreeItem>();
		List<Map.Entry<String, DokuNSElement>> entrylist = new ArrayList(
				namespace.getChildren().entrySet());
		Collections.sort(entrylist, new Comparator() {
			public int compare(Object o1, Object o2) {
				return ((Map.Entry<String, DokuNamespace>) o1).getKey()
						.compareTo(
								((Map.Entry<String, DokuNamespace>) o2)
										.getKey());
			}
		});
		for (Map.Entry<String, DokuNSElement> me : entrylist) {
			if (me.getValue().getClass() == DokuNamespace.class) {
				String name = ((DokuNamespace) me.getValue()).getName();
				TreeItem treeItem;
				if (!checklist.containsKey(name)) {
					treeItem = new TreeItem(tree, 0);
					treeItem.setText(name);
					checklist.put(name, treeItem);
					pageMap.put(treeItem, null);
				} else {
					treeItem = checklist.get(name);
				}
				setTreeItem(treeItem, (DokuNamespace) me.getValue());
			} else if (me.getValue().getClass() == DokuPage.class) {
				String name = ((DokuPage) me.getValue()).getName();
				if (!checklist.containsKey(name)) {
					TreeItem treeItem = new TreeItem(tree, 0);
					treeItem.setText(name);
					checklist.put(name, treeItem);
					pageMap.put(treeItem, (DokuPage) me.getValue());
				} else {
					TreeItem treeItem = checklist.get(name);
					pageMap.remove(treeItem);
					pageMap.put(treeItem, (DokuPage) me.getValue());
				}
			}
		}
	}
}
